/* hal_clock.h */

#ifndef __HAL_CLOCK_H__
#define __HAL_CLOCK_H__

#include "hal_common.h"

#define CLOCK_MAKE_PERIPH_ID(group, subid)  (((group) << 5u) | ((subid) & ((1u << 5u) - 1u)))
#define CLOCK_GET_PERIPH_GROUP(periph_id)   ((periph_id) >> 5u)
#define CLOCK_GET_PERIPH_SUBID(periph_id)   ((periph_id) & ((1u << 5u) - 1u))

#define CLOCK_PERIPH_ID_GPIO0   CLOCK_MAKE_PERIPH_ID(0u, 0u)
#define CLOCK_PERIPH_ID_GPIO1   CLOCK_MAKE_PERIPH_ID(0u, 1u)
#define CLOCK_PERIPH_ID_DMA     CLOCK_MAKE_PERIPH_ID(0u, 5u)
#define CLOCK_PERIPH_ID_SPI1    CLOCK_MAKE_PERIPH_ID(0u, 6u)
#define CLOCK_PERIPH_ID_UART0   CLOCK_MAKE_PERIPH_ID(0u, 9u)
#define CLOCK_PERIPH_ID_UART1   CLOCK_MAKE_PERIPH_ID(0u, 10u)
#define CLOCK_PERIPH_ID_I2C0    CLOCK_MAKE_PERIPH_ID(0u, 13u)
#define CLOCK_PERIPH_ID_TMR0    CLOCK_MAKE_PERIPH_ID(0u, 15u)
#define CLOCK_PERIPH_ID_TMR1    CLOCK_MAKE_PERIPH_ID(0u, 16u)
#define CLOCK_PERIPH_ID_TMR2    CLOCK_MAKE_PERIPH_ID(0u, 17u)
#define CLOCK_PERIPH_ID_TMR3    CLOCK_MAKE_PERIPH_ID(0u, 18u)
#define CLOCK_PERIPH_ID_ADC     CLOCK_MAKE_PERIPH_ID(0u, 23u)
#define CLOCK_PERIPH_ID_CNN     CLOCK_MAKE_PERIPH_ID(0u, 25u)
#define CLOCK_PERIPH_ID_I2C1    CLOCK_MAKE_PERIPH_ID(0u, 28u)
#define CLOCK_PERIPH_ID_PT0     CLOCK_MAKE_PERIPH_ID(0u, 29u)


#define CLOCK_PERIPH_ID_GPIO2   CLOCK_MAKE_PERIPH_ID(2u, 0u)
#define CLOCK_PERIPH_ID_WDT1    CLOCK_MAKE_PERIPH_ID(2u, 1u)
#define CLOCK_PERIPH_ID_TMR4    CLOCK_MAKE_PERIPH_ID(2u, 2u)
#define CLOCK_PERIPH_ID_TMR5    CLOCK_MAKE_PERIPH_ID(2u, 3u)
#define CLOCK_PERIPH_ID_UART3   CLOCK_MAKE_PERIPH_ID(2u, 4u)
#define CLOCK_PERIPH_ID_LPCOMP  CLOCK_MAKE_PERIPH_ID(2u, 6u)

void CLOCK_EnablePeriph(uint32_t periph_id, bool enable);

/* for GCR->RES0 */
#define CLOCK_RESET_ID_SYS     CLOCK_MAKE_PERIPH_ID(0, 31u)
#define CLOCK_RESET_ID_PERIPH  CLOCK_MAKE_PERIPH_ID(0, 30u)
#define CLOCK_RESET_ID_SOFT    CLOCK_MAKE_PERIPH_ID(0, 29u)
#define CLOCK_RESET_ID_UART2   CLOCK_MAKE_PERIPH_ID(0, 28u)
#define CLOCK_RESET_ID_ADC     CLOCK_MAKE_PERIPH_ID(0, 26u)
#define CLOCK_RESET_ID_CNN     CLOCK_MAKE_PERIPH_ID(0, 25u)
#define CLOCK_RESET_ID_TRNG    CLOCK_MAKE_PERIPH_ID(0, 24u)
#define CLOCK_RESET_ID_SMPHR   CLOCK_MAKE_PERIPH_ID(0, 22u)
#define CLOCK_RESET_ID_RTC     CLOCK_MAKE_PERIPH_ID(0, 17u)
#define CLOCK_RESET_ID_I2C0    CLOCK_MAKE_PERIPH_ID(0, 16u)
#define CLOCK_RESET_ID_SPI1    CLOCK_MAKE_PERIPH_ID(0, 13u)
#define CLOCK_RESET_ID_UART1   CLOCK_MAKE_PERIPH_ID(0, 12u)
#define CLOCK_RESET_ID_UART0   CLOCK_MAKE_PERIPH_ID(0, 11u)
#define CLOCK_RESET_ID_TMR3    CLOCK_MAKE_PERIPH_ID(0, 8u)
#define CLOCK_RESET_ID_TMR2    CLOCK_MAKE_PERIPH_ID(0, 7u)
#define CLOCK_RESET_ID_TMR1    CLOCK_MAKE_PERIPH_ID(0, 6u)
#define CLOCK_RESET_ID_TMR0    CLOCK_MAKE_PERIPH_ID(0, 5u)
#define CLOCK_RESET_ID_GPIO1   CLOCK_MAKE_PERIPH_ID(0, 3u)
#define CLOCK_RESET_ID_GPIO0   CLOCK_MAKE_PERIPH_ID(0, 2u)
#define CLOCK_RESET_ID_WDT0    CLOCK_MAKE_PERIPH_ID(0, 1u)
#define CLOCK_RESET_ID_DMA     CLOCK_MAKE_PERIPH_ID(0, 0u)


#define CLOCK_RESET_ID_I2C1    CLOCK_MAKE_PERIPH_ID(0, 31u)
#define CLOCK_RESET_ID_I2C2    CLOCK_MAKE_PERIPH_ID(0, 31u)

void CLOCK_ResetPeriph(uint32_t reset_id);

typedef enum
{
    CLOCK_ClkSrc_ISO    = 0u, /* SysclkSel */
    CLOCK_ClkSrc_INRO   = 3u, /* SysclkSel */
    CLOCK_ClkSrc_IPO    = 4u, /* SysclkSel */
    CLOCK_ClkSrc_IBRO   = 5u, /* SysclkSel */
    CLOCK_ClkSrc_ERTCO  = 6u, /* SysclkSel */
    CLOCK_ClkSrc_ExtClk = 7u, /* SysclkSel */
} CLOCK_ClkSrc_Type;


void CLOCK_SetSysclkSel(CLOCK_ClkSrc_Type src, uint32_t div);
void CLOCK_EnableClkSrc(CLOCK_ClkSrc_Type src);
void CLOCK_DisableClkSrc(CLOCK_ClkSrc_Type src);

#if 0
void CLOCK_DelayUs(uint32_t us);
void CLOCK_DelayMs(uint32_t ms);
#endif

#endif /* __HAL_CLOCK_H__ */

